PATH
MacOS X Server Release Notes Copyright © 1998 by Apple Computer, Inc. All Rights Reserved.
The Java APIs for the core Yellow Box frameworks rest upon the foundation of Apple's Java/Objective-C integration technology (also known as the "Java Bridge"). This technology allows you to access the full potential of the Yellow Box frameworks using Java code and without having to write any Objective-C code. The bridge even allows you to subclass Objective-C objects in Java; in addition, using the bridging tools, you can wrap your own Objective-C code to make it accessible to Java applications.
In the first Developer Release, the Java APIs for the Application and Foundation frameworks were distributed in their alpha form. They have since undergone many changes and are now considerably more robust and finalized. Using these APIs, you can access virtually all of the classes and protocols that make up the Application and Foundation frameworks.
In Developer Release 2, alpha versions of the APIs were still shipping with Rhapsody (but not Yellow Box for Windows). They have now been removed.
There is a script to facilitate the conversion of application
sources from the alpha APIs to the new APIs. The script does not
provide complete coverage, but it will take care of most of the
more straightforward cases, freeing you from some tedious
conversion work. You can find the script and instructions on how
to use it in /System/Developer/Java/Conversion/AlphaToYellow
.
Be sure to make a copy of your source directory before you apply
the conversion, as the script works in place. Once you have run
the scripts, trying to compile your program should pinpoint the
remaining areas where conversion is still needed.
Note: On Yellow Box for Windows systems, whenever
installed Rhapsody directories and files are referenced in this
release note, substitute the Yellow Box for Windows installation
directory for /System
. For example, in the above
example, substitute installed_dir/Developer/Java/Conversion/AlphaToYellow
for /System/Developer/Java/Conversion/AlphaToYellow
.
A potential substantial leak in the bridge has been fixed. Pure Java objects (that is, objects (A that do not inherit from com.apple.yellow.foundation.NSObject) that crossed the bridge would not be autoreleased properly . They now are, but this change may lead to a crash in your applications developed under DR2.
The underlying problem is that Objective C frameworks are not garbage collected and we have no formal notion of a weak reference. Instead, we rely on convention to say that delegates must be retained by somebody else. If there are no retained references in the Objective C space to these pure Java objects, then the Objective C proxy to the Java object is dealloc'd when the autorelease pool is cleaned up and the delegate pointers are left dangling. Applications such as TextEdit solve this problem by first storing in an NSArray those Java objects that would otherwise only be weakly referenced in the Objective C space. The objects are removed from the array at some "appropriate time" (after first cleaning up all weak references in the Objective C space), which then permits the object to be garbage collected. For example, TextEdit's Document object is stored in a global array for the lifetime of the document. When the document window is closed, the Document object removes itself from the NSNotificationCenter, sets the window's delegate to null, and finally removes itself from the global array.
To facilitate the migration from DR2, we have added the capability to turn on this leak in the bridge. If your app begins crashing with "message sent to freed object" type errors, you can try turning on the leak to see if you have been affected by this bug. This can be done in two ways:
1) via an environment variable:
setenv BRIDGEStopLeakingObjects NO
MyApp.app/MyApp
2) via user defaults:
MyApp.app/MyApp -BRIDGEStopLeakingObjects NO
or:
defaults write MyApp BRIDGEStopLeakingObjects NO
Setting the NSZombieEnabled debugging flag to YES can be immensly helpful in tracking down these problems. See Foundation/NSDebug.h for details.
com.apple.yellow.application
and com.apple.yellow.foundation.
(The alpha
packages were named com.apple.alpha.app
and com.apple.alpha.core
.)
In addition, the same class and interface names are used in the Objective-C and Java APIs; thus the Objective-C prefixes are retained (NSApplication instead of Application, EOQualifier instead of Qualifier, etc).
replaceCharactersInRange:withAttributedString:
and replaceCharactersInRange:withString:
are
now both represented as replaceCharactersInRange()
in the Java APIs.Examples:
-(NSDictionary)attributesAtIndex:(int)index
effectiveRange:(NSRangePointer)range
maps to
NSDictionary attributesAtIndex(int index, NSMutableRange
range)
void NSRectFillList(const NSRect *rects, int
count)
maps to
void fillRectList(NSRect[] rects)
Along the same lines, mutable versions of other classes (for example, NSDictionary) are used in APIs which pass these classes by reference in order to get a value back from the caller.
setObjectForKey()
method in NSDictionary in Java now checks to see whether
the object is a instance of a class corresponding to
these structs. These are converted to an NSValue before
being stored in the dictionary. In addition objectForKey()
performs the reverse mapping. This allows the storage of
these kinds of values in NSDictionaries to happen
naturally from both Java and Objective-C. Note that the
NSNumber to Number conversion already happens in all
cases. Examples of this include NSScreen's deviceDescription(),
which returns a dictionary, and
NSAttributedString's RTFFromRange()
, which
takes a dictionary as an argument.
Two limitations of this feature are:
valueWithRect:
instead
of valueWithBytes:objCType:
);
otherwise the automatic conversion won't take
place.Note that in general morphing is the right thing to do: You want to communicate strings in Java using Java's built-in java.lang.String class. Like NSString, this class stores a string of Unicode characters and provides API to deal with them. Thus most of the Yellow Box API in Java still takes or returns String, which is automatically converted to and from an NSString.
NSImage(URL)
in addition to the
constructors taking file name as a String. Similarly, you
can use the NSOpenPanel method URLs()
to get
back an array of URLs that represent the files selected
by the user. Although these methods currently work only
with URLs representing local files, they will soon work
with other types of URLs. In addition, additional APIs
that take or return URLs will be added throughout the
frameworks where appropriate.fileAttributes(),
setFileAttributes(), pathFromURL(), URLWithPath(),
and searchPathForDirectoriesInDomains()
.
These cover functionality available in Objective-C
through functions or unexposed classes.push()
and pop()
are exposed in Java. They should rarely be needed.
loadNibNamed()
, which is added by the
Application Kit, is available in NSApplication in Java.com.apple.yellow.foundation._private
should be considered private and not used in your
applications. Similarly, com.apple.yellow.application._NSObsoleteMenuItemProtocol
is also private and should not be used.[NSView initWithFrame:rect
], you
use NSView(rect)
to create views. This of
course is the most natural way for Java, although
sometimes the set of constructors might seem confusing.
For instance, NSAttributedString provides the following
constructors: NSAttributedString(String);
(from
a string)
NSAttributedString(String, NSDictionary);
(from
a string and attributes)
NSAttributedString(URL, NSMutableDictionary);
(from
the specified file, returning document properties)
NSAttributedString(NSData, NSMutableDictionary);
(from
the specified file contents, returning document
properties)
NSAttributedString(NSFileWrapper,
NSMutableDictionary);
(from the specified file
contents, returning document properties)
NSAttributedString(NSData, URL,
NSMutableDictionary);
(from the specified HTML
file contents and base URL, returning doc properties)
In some cases, multiple initialization methods have
been mapped to a single constructor in Java with multiple
arguments; for instance, NSImage's initByReferencingFile:
and initWithContentsOfFile:
both map to NSImage(String,
boolean)
, with the boolean indicating whether to
reference (YES) or not (NO). Note that use of URLs to
represent files also eliminates some of these cases.
Finally, in other cases, static methods are used
instead of constructors. This not only reduces the
confusion associated with having many constructors, it
also allows substitution of objects if necessary. NSColor
is an example of this, with methods such as colorWithCalibratedRGB()
,
colorWithDeviceCMYK()
, blackColor()
,
scrollBarColor()
, and so on.
retain
. If an object is created
in Java, and passed across the bridge into Objective-C,
and it is not retained by anyone on the Objective-C side,
the object's proxy will get released, causing the weak
references on the Objective-C side to be invalidated,
thereby causing invalid memory access. One way to work
around this is to ensure that such objects are referenced
strongly (that is, retained) in the Objective-C side; you
can assure this by putting such objects into an NSArray.
TextEdit does this with its Document objects.